using System;

using MVPComposibility.ContactManager.DomainModel;
using MVPComposibility.ContactManager.Views.ContactDetails;
using MVPComposibility.ContactManager.Views.ContactManager;

using WCSFContrib.Extensions.Utility;

namespace MVPComposibility.ContactManager.Views.ContactDetails
{
	public class ContactDetailsModel : IContactDetailsModel
	{
		private Contact _contact;
		private Contact _editedContact;

		public event EventHandler ContactChanged;
		public event EventHandler EditCompleted;
		public event EventHandler<DataEventArgs<NewContactName>> ContactNameChanged;

		public Contact Contact
		{
			get { return _contact; }
			set
			{
				_contact = value;
				_editedContact = _contact != null ? (Contact)_contact.Clone() : null;
				OnContactChanged(EventArgs.Empty);
			}
		}

		public virtual void RestoreContactFromPersistentState(Contact c)
		{
			_contact = c;
			_editedContact = _contact != null ? (Contact)_contact.Clone() : null;
		}

		public void RestoreContact(Contact contact)
		{
			RestoreContactFromPersistentState(contact);
		}

		public Contact EditedContact
		{
			get { return _editedContact; }
		}

		public void EditComplete()
		{
			if (_editedContact == null)
				return;

			if (!_contact.Name.Equals(_editedContact.Name))
			{
				_contact.Name = _editedContact.Name;
				// Note: Only when the name changes this event is invoked.
				onContactNameChanged(_editedContact.Id, _editedContact.Name);
			}
			_contact.ClearAddresses();
			foreach (Address a in _editedContact.Addresses)
			{
				_contact.AddAddress(a);
			}
			OnEditCompleted(EventArgs.Empty);
		}

		private void onContactNameChanged(int id, string name)
		{
			if (ContactNameChanged != null)
			{
				ContactNameChanged(this, new DataEventArgs<NewContactName>(new NewContactName(id, name)));
			}
		}

		public void EditCancel()
		{
			_editedContact = _contact != null ? (Contact)_contact.Clone() : null;
		}

		protected virtual void OnContactChanged(EventArgs e)
		{
			if (ContactChanged != null)
			{
				ContactChanged(this, e);
			}
		}

		protected virtual void OnEditCompleted(EventArgs e)
		{
			if (EditCompleted != null)
			{
				EditCompleted(this, e);
			}
		}

		public void SetSelectedContact(Contact contact)
		{
			Contact = contact;
		}
	}
}